#pragma once

#include "U7FileDefs.h"
#include "Graphic.h"

void GetShapeFrameInfo(
	const PSHAPEENTRY shapeEntry,
	long shapeLength,
	int frameIndex,
	POINT& hotspot,
	SIZE& dimension );

void DrawShapeTile(
	PGRAPHIC pGraphic,
	const TILE tile,
	int anchorX,
	int anchorY );

void DrawShapeFrame(
	PGRAPHIC pGraphic,
	const PFRAMEENTRY frameEntry,
	int anchorX,
	int anchorY );

void DrawShape(
	PGRAPHIC pGraphic,
	const PSHAPEENTRY shapeEntry,
	long shapeLength,
	long frameIndex,
	int anchorX,
	int anchorY );

bool HitTest(
	const PFRAMEENTRY frameEntry,
	int anchorX,
	int anchorY,
	int hitX,
	int hitY );


inline
PSHAPEENTRY GetShape( const char* shapeFile, int shapeIndex, long& shapeLength )
{
	PFLEXFILEHEADER header = (PFLEXFILEHEADER)shapeFile;
	if ( shapeIndex < header->count )
	{
		PFLEXFILEENTRY entry = (PFLEXFILEENTRY)(header+1) + shapeIndex;
		PSHAPEENTRY shapeEntry = (PSHAPEENTRY)(shapeFile + entry->offset);
		shapeLength = entry->size;
		return shapeEntry;
	}
	return NULL;
}

inline
bool IsShapeTile( const PSHAPEENTRY shapeEntry, long shapeLength )
{
	return ( shapeLength != shapeEntry->size ); // tile
}

inline
int GetShapeFrameCount( const PSHAPEENTRY shapeEntry, long shapeLength )
{
	if ( shapeLength != shapeEntry->size ) // tile
		return shapeLength / TILE_LENGTH;
	else
		return shapeEntry->offset[0]/sizeof(long) - 1;
}

inline
PFRAMEENTRY GetShapeFrame( const PSHAPEENTRY shapeEntry, long shapeLength, int frameIndex )
{
	if ( shapeLength == shapeEntry->size
		&& frameIndex < (int)(shapeEntry->offset[0]/sizeof(long)-1) )
	{
		return (PFRAMEENTRY)((char*)shapeEntry + shapeEntry->offset[frameIndex]);
	}
	ASSERT(FALSE);
	return NULL;
}

inline
TILE GetShapeTile( const PSHAPEENTRY shapeEntry, long shapeLength, int frameIndex )
{
	// for chunk pattern 1844, something wrong
	int maxFrames = shapeLength / TILE_LENGTH;
	if ( shapeLength != shapeEntry->size )
	{
		return (TILE)((char*)shapeEntry + TILE_LENGTH * (frameIndex%maxFrames));
	}
	ASSERT(FALSE);
	return NULL;
}

inline
void GetShapeTileInfo( POINT& hotspot, SIZE& dimension )
{
	hotspot.x = TILE_WIDTH - 1;
	hotspot.y = TILE_HEIGHT - 1;
	dimension.cx = TILE_WIDTH;
	dimension.cy = TILE_HEIGHT;
}

inline
void GetShapeFrameInfo( const PFRAMEENTRY frameEntry, POINT& hotspot, SIZE& dimension )
{
	hotspot.x = frameEntry->leftX + 1;
	hotspot.y = frameEntry->topY + 1;
	dimension.cx = frameEntry->leftX + 1 + frameEntry->rightX;
	dimension.cy = frameEntry->topY + 1 + frameEntry->bottomY;
}

inline
void DrawShape(
	PGRAPHIC pGraphic,
	const char* shapeFile,
	PSHAPEID shapeID,
	int anchorX,
	int anchorY )
{
	long shapeLength;
	PSHAPEENTRY shapeEntry = GetShape( shapeFile, shapeID->shapeType, shapeLength );
	DrawShape( pGraphic, shapeEntry, shapeLength, shapeID->shapeFrame, anchorX, anchorY );
}